/*
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 *
 * Copyright @2008 the original author or authors.
 */
package com.bluestone.core;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.net.Socket;
import java.util.Vector;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.entity.SerializableEntity;
import org.apache.http.impl.DefaultHttpClientConnection;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

import com.bluestone.proxy.DataFilter;
import com.bluestone.proxy.DefaultDataFilter;
import com.bluestone.proxy.HttpClient;
import com.bluestone.proxy.InterceptCommand;
import com.bluestone.proxy.InterceptData;
import com.bluestone.util.Util;

/**
 * @author <a href="mailto:bluesotne.master@gmail.com">daniel.q</a>
 *
 */
public class InterceptAction extends Action {
	protected String spitRegex = "\\|";

	public InterceptAction(String type, String target, String value,
			String delay, String offset) {
		super(type, target, value, delay, offset);
	}

	static String[] contents = null;

	/**
	 * Init the pageContent.If the value of the target is "newpage",then reset the pageContent. 
	 */
	@Override
	public boolean execute() {
		if (!super.execute()) {
			return false;
		}
		
		//check proxy setting
		if(Util.getCurrentProject().getProxy() == null){
			Util.warn("should set proxy server in project file!");
			return false;
		}
		
		if(Attributes.START.equalsIgnoreCase(target)){
			return startInterceptRequest();
		}else if(Attributes.STOP.equalsIgnoreCase(target)){
			return stopInterceptRequest();
		}else{
			return false;
		}

	}
	
	private boolean stopInterceptRequest(){
		BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
				"POST", "/bluestone/intercept.do");

		InterceptCommand command = new InterceptCommand();
		command.setCommand(InterceptCommand.STOPINTERCEPT);
		
		try {
			SerializableEntity entity = new SerializableEntity(
					command, true);
			request.setEntity(entity);
			HttpContext context = new BasicHttpContext();
			HttpClient client = new HttpClient(context);
			DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
			int port = Util.getCurrentProject().getProxy().getHttpport();
			String servername = Util.getCurrentProject().getProxy().getServername();
			
			HttpHost host = new HttpHost(servername, port);
			if (!conn.isOpen()) {
				Socket socket = new Socket(host.getHostName(), host.getPort());
				conn.bind(socket, client.getParams());
			}
			HttpResponse response = client.execute(request, host, conn);
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
	            HttpEntity httpentity = response.getEntity();
	    		byte [] bytes = EntityUtils.toByteArray(httpentity);    		
	    		ByteArrayInputStream in = new ByteArrayInputStream(bytes);    		
	    		ObjectInputStream objin = new ObjectInputStream(in);    		
	    		try {
					Object obj = objin.readObject();
					if(Vector.class.isInstance(obj)){
						Vector v = (Vector)obj;
						StringBuffer buffer = new StringBuffer();
						for(int i=0; i< v.size(); i++){
							InterceptData interceptdata = (InterceptData)v.get(i);
							byte [] temp  = interceptdata.getContent();
							String charset = (String)interceptdata.getHeaders().get(HTTP.CONTENT_ENCODING);
							buffer.append(new String(temp));							
						}
						
						//copy content to system clipboard
						Transferable tText = new StringSelection(buffer.toString());
						Clipboard sysc = Toolkit.getDefaultToolkit().getSystemClipboard();		
						sysc.setContents(tText, null);						
					}
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}else{
				return false;
			}

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}  
		return true;
	}
    private boolean startInterceptRequest(){
		BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest(
				"POST", "/bluestone/intercept.do");

		InterceptCommand command = new InterceptCommand();
		command.setCommand(InterceptCommand.STARTINTERCEPT);
		
		//set filter content type
		if(value!=null){
			DataFilter filter = new DefaultDataFilter();
			filter.setContentType(value);
			command.setFilter(filter);
		}
		try {
			SerializableEntity entity = new SerializableEntity(
					command, true);
			request.setEntity(entity);
			HttpContext context = new BasicHttpContext();
			HttpClient client = new HttpClient(context);
			DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
			int port = Util.getCurrentProject().getProxy().getHttpport();
			String servername = Util.getCurrentProject().getProxy().getServername();
			
			HttpHost host = new HttpHost(servername, port);
			if (!conn.isOpen()) {
				Socket socket = new Socket(host.getHostName(), host.getPort());
				conn.bind(socket, client.getParams());
			}
			HttpResponse response = client.execute(request, host, conn);
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				return true;
			}else{
				return false;
			}

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}   
    }
    
	protected void getContents() {

	}
}
